home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / comm / mail / thor201.lha / THOR_2.0 / thor.lha / rexx / SortMail.thor < prev    next >
Text File  |  1995-05-15  |  18KB  |  601 lines

  1. /*
  2. ** $VER: SortMail.thor 1.4 (2.5.95) Eirik Synnes
  3. **
  4. ** Some code borrowed from  AddSOUP.thor      by Magne Østlyngen
  5. **                     and  AddAmiNetList.br  by Petter Nilsen
  6. **
  7. ** Todo:  Test ShowMessage
  8. **        Use from field for finding mailing list msgs
  9. **        UUDecode Amiga Link
  10. **        Use copyback cache more efficiently
  11. **        Check for duplicate entries in the filebase
  12. **        Support SuperUnread flag in mailing list msgs (waiting for support...)
  13. **        Mark Amiga Report as read (waiting for support...)
  14. **
  15. ** Ideas: Parse messages from the Usenet Oracle
  16. **
  17. */
  18.  
  19. options results
  20.  
  21. signal on break_c
  22. signal on halt
  23.  
  24. /* Initialize some variables */
  25. system = ""; mailconf = ""
  26. aminet = ""; amirep = ""; checkcc= 0; stats = 0
  27. mlcount = 0; dgcount = 0
  28. mlfound = 0; dgparsed = 0 ; dgsubmsgs = 0; rparsed = 0; rfiles = 0; aruu = 0;
  29. progwin = 0; delnew = 0
  30.  
  31. MDB_DELETED             =  5  /* Message is deleted. */
  32.  
  33. /* Find Thor and BBSREAD ARexx ports' */
  34. p=address()||' '||show('P',,);if pos('THOR.',p)>0 then thorport=word(substr(p,pos('THOR.',p)),1);else do;say 'No THOR port found!';exit(0);end
  35. if ~show('p', 'BBSREAD') then do; address command; "run >nil: `GetEnv THOR/THORPath`bin/LoadBBSRead"; "WaitForPort BBSREAD"; end
  36.  
  37. /* See if another copy of SortMail is already running */
  38. if exists("T:SortMail.tmp") then do
  39.  REQUESTNOTIFY '"Another copy of SortMail\nis probably running."' '"_Continue|_Abort"'
  40.  if result = 0 then exit(0)
  41.  end
  42.  
  43. call open(tmp, "T:SortMail.tmp", 'W'); call close(tmp)
  44.  
  45. /* Get the path of the configuration file */
  46. call open(pn, 'ENV:Thor/THORPATH', 'R')
  47. thorpath = readln(pn)
  48. call close(pn)
  49.  
  50. if ~exists(thorpath'rexx') then cfgfile = 'ENV:Thor/SortMail.cfg'
  51. else cfgfile = thorpath'rexx/SortMail.cfg'
  52.  
  53. if ~exists(cfgfile) then do
  54.  REQUESTNOTIFY '"Couldn''t find config file ('cfgfile').\nPlease run CfgSortMail.thor and try again."' '"Abort"'
  55.  call cleanup
  56.  end
  57.  
  58. /* Check if user has entered a system or is in the startup window */
  59. address(thorport)
  60. CURRENTBBS STEM bbs
  61. if rc = 1 then do
  62.  REQUESTNOTIFY '"Enter your configured system\nbefore running this script."' '"Abort"'
  63.  call cleanup
  64.  end
  65. else if rc ~= 0 then do
  66.  REQUESTNOTIFY '"'THOR.LASTERROR'"' '"Abort"'
  67.  call cleanup
  68.  end
  69.  
  70. /* Read configuration */
  71. call readcfg
  72.  
  73. if system ~= bbs.BBSNAME then call cleanup
  74.  
  75. /* Get some info on the system */
  76. address(bbsread)
  77. GETCONFLIST BBSNAME '"'system'"' STEM conflist
  78. if rc ~=0 then do
  79.  address(thorport)
  80.  REQUESTNOTIFY '"'BBSREAD.LASTERROR'"' '"Abort"'
  81.  call cleanup
  82.  end
  83.  
  84. address(thorport)
  85. GETMESSAGEARRAY '"'mailconf'"' msgs LS
  86. if rc = 5 then do
  87.  call cleanup
  88.  end
  89. else if rc ~= 0 then do
  90.  REQUESTNOTIFY '"'THOR.LASTERROR'"' '"Abort"'
  91.  call cleanup
  92.  end
  93.  
  94. /* Exit if there are no messages to process */
  95. if msgs.count = 0 then call cleanup
  96.  
  97. OPENPROGRESS TITLE '"Sorting messages..."' TOTAL msgs.count AT "_Abort" PROGRESSCHARWIDTH 38
  98. progwin = result
  99.  
  100. /* Start of main loop */
  101. do curr = 1 to msgs.count
  102.  msgfini = 0; textread = 0
  103.  
  104.  /* Update progressbar */
  105.  address(thorport)
  106.  UPDATEPROGRESS REQ progwin CURRENT curr PT '"Message 'curr' of 'msgs.count' (OrgMsg: 'msgs.curr')"'
  107.  
  108.  /* Read message data */
  109.  address(bbsread)
  110.  drop data. head.
  111.  READBRMESSAGE '"'system'"' '"'mailconf'"' msgs.curr DATASTEM data HEADSTEM head
  112.  if rc ~= 0 then do
  113.   address(thorport)
  114.   REQUESTNOTIFY '"Couldn''t read msg #'msgs.curr':\n'BBSREAD.LASTERROR'"' '"_Ok"'
  115.   call cleanup
  116.   end
  117.  
  118.  if bittst(data.FLAGS,MDB_DELETED) then msgfini = 1
  119.  
  120.  /* Check if message is part of a mailing list */
  121.  if mlcount > 0 then do
  122.   do m = 1 to mlcount until msgfini = 1
  123.    searchaddr = upper(compress(head.TOADDR, ',<>()"'))
  124.    do n = 1 to mlist.m.addrcount until msgfini = 1
  125.     if find(searchaddr, upper(mlist.m.toaddr.n)) > 0 then do
  126.      call movemsg(msgs.curr, mlist.m.name, mlist.m.replyaddr)
  127.      mlfound = mlfound + 1
  128.      msgfini = 1
  129.      end
  130.     end
  131.    if msgfini = 0 then do n = 1 to mlist.m.namecount until msgfini = 1
  132.     if upper(head.TONAME) = upper(mlist.m.toname.n) then do
  133.      call movemsg(msgs.curr, mlist.m.name, mlist.m.replyaddr)
  134.      mlfound = mlfound + 1
  135.      msgfini = 1
  136.      end
  137.     end
  138.    end
  139.   end
  140.  
  141.  if msgfini = 1 then iterate curr
  142.  
  143.  /* Check if message is a digest */
  144.  if dgcount > 0 then do
  145.   do m = 1 to dgcount until msgfini = 1
  146.    do n = 1 to digest.m.addrcount until msgfini = 1
  147.     if find(upper(head.TOADDR), upper(digest.m.toaddr.n)) > 0 then do
  148.      call parsedigest(msgs.curr, digest.m.name, digest.m.replyaddr, digest.m.endsubmsg, digest.m.enddigest, digest.m.deldigest)
  149.      dgparsed = dgparsed + 1
  150.      msgfini = 1
  151.      end
  152.     end
  153.    if msgfini = 0 then do n = 1 to digest.m.namecount until msgfini = 1
  154.     if upper(head.TONAME) = upper(digest.m.toname.n) then do
  155.      call parsedigest(msgs.curr, digest.m.name, digest.m.replyaddr, digest.m.endsubmsg, digest.m.enddigest, digest.m.deldigest)
  156.      dgparsed = dgparsed + 1
  157.      msgfini = 1
  158.      end
  159.     end
  160.    end
  161.   end
  162.  
  163.  if msgfini = 1 then iterate curr
  164.  
  165.  select 
  166.   /* Check if message is a aminet recent message */
  167.   when head.TOADDR = aminet then call parseaminet(msgs.curr)
  168.  
  169.   /* Check if message contains amiga report (not implemented yet) */
  170.   when head.FROMADDR = amirep then do
  171.    if exists(thorpath'rexx/UUDecode.thor') then do
  172.     address(thorport)
  173.     SAVEMESSAGE BBSNAME '"'system'"' CONFNAME '"'mailconf'"' MSGNUMBER msgs.curr NOHEADER NOANSI FILENAME '"T:AmiRep.uu"'
  174.     address(command)
  175.     'rx 'thorpath'rexx/UUDecode.thor T:AmiRep.uu'
  176.     aruu = aruu + 1
  177.     end
  178.    else do
  179.     address(thorport)
  180.     REQUESTNOTIFY '"Couldn''t uudecode Amiga Report:\n'thorpath'rexx/UUDecode.thor not found."' '"I see."'
  181.     end
  182.    end
  183.  
  184.   otherwise if msgfini = 0 then do
  185.    /* Check Cc:, Resent-To: and Apparently-To fields */
  186.    if checkcc = 1 then do
  187.     drop text.
  188.     address(bbsread)
  189.     READBRMESSAGE '"'system'"' '"'mailconf'"' msgs.curr TEXTSTEM text
  190.     textread = 1
  191.     if text.COMMENT.COUNT > 0 then do n = 1 to text.COMMENT.COUNT
  192.      if upper(left(text.COMMENT.n, 3)) = 'CC:' | upper(left(text.COMMENT.n, 14)) = 'APPARENTLY-TO:' | upper(left(text.COMMENT.n, 10)) = 'RESENT-TO:' then do m = 1 to mlcount until msgfini = 1
  193.       ccs = upper(compress(subword(text.COMMENT.n, 2), ',<>()'))
  194.       do o = 1 to mlist.m.addrcount until msgfini = 1
  195.        if find(ccs, upper(mlist.m.toaddr.o)) > 0 then do
  196.         call movemsg(msgs.curr, mlist.m.name, mlist.m.replyaddr)
  197.         mlfound = mlfound + 1
  198.         msgfini = 1
  199.         end
  200.        end
  201.       end
  202.      end
  203.     end
  204.    end
  205.   end
  206.  end
  207.  
  208. cnt = 1
  209. if mlfound > 0 | dgparsed > 0 | rparsed > 0 & stats = 1 then do
  210.  msgstem.TEXT.cnt = 'Sortmail processed 'msgs.count' message(s) and found:'; cnt = cnt + 1
  211.  msgstem.TEXT.cnt = ''; cnt = cnt + 1
  212.  if mlfound > 0 then do; msgstem.TEXT.cnt = mlfound' maillist message(s)'; cnt = cnt + 1; end
  213.  if dgparsed > 0 then do; msgstem.TEXT.cnt = dgparsed' digest message(s) containing 'dgsubmsgs' sub-message(s)'; cnt = cnt + 1; end
  214.  if rparsed > 0 then do; msgstem.TEXT.cnt = rparsed' AmiNet RECENT message(s) reporting 'rfiles' new files'; cnt = cnt + 1; end
  215.  end
  216. if amirep ~= '' & aruu > 0 then do; msgstem.TEXT.cnt = 'AmigaReport (uudecoded and put in your download directory)'; cnt = cnt + 1; end
  217.  
  218. msgstem.TEXT.COUNT = cnt - 1
  219. if msgstem.TEXT.COUNT > 0 then call writemsg
  220.  
  221. /* Update message list in Thor if the user is in the E-Mail conference */
  222. address(thorport)
  223. CURRENTBBS STEM bbs
  224. if bbs.CONFNAME = mailconf then SHOWCONFERENCE '"'mailconf'"'
  225. UPDATECONFWINDOW
  226.  
  227. break_c:
  228. halt:
  229. call cleanup
  230.  
  231.  
  232. /*
  233. ** Procedures
  234. */
  235.  
  236. writemsg: procedure expose thorport system mailconf msgstem.
  237. address(bbsread)
  238. GETBBSDATA '"'system'"' bbsdata
  239. msgstem.FROMNAME = bbsdata.USERNAME
  240. msgstem.TONAME = bbsdata.USERNAME
  241. msgstem.SUBJECT = 'SortMail results'
  242. WRITEBRMESSAGE '"'system'"' '"'mailconf'"' STEM msgstem
  243. return
  244.  
  245.  
  246. parsedigest: procedure expose thorport system mailconf conflist. data. head. dgsubmsgs
  247.              parse arg number, toconf, repaddr, endsubmsg, enddigest, deldigest
  248.  
  249. address(bbsread)
  250. READBRMESSAGE '"'system'"' '"'mailconf'"' number TEXTSTEM text
  251. if rc ~= 0 then do
  252.  address(thorport)
  253.  REQUESTNOTIFY '"Couldn''t read msg #'msgs.curr':\n'BBSREAD.LASTERROR'"' '"_Ok"'
  254.  return
  255.  end
  256.  
  257. line = 1
  258.  
  259. BUFMODE COPYBACK
  260.  
  261. do forever
  262.  drop newmsg.
  263.  newmsg.msgid = head.msgid
  264.  newmsg.replyconf = mailconf
  265.  newmsg.replyaddr = repaddr
  266.  newmsg.text.count = 0
  267.  fromline = 0; subjline = 0; dateline = 0
  268.  counted = 0; msgoffset = 0
  269.  
  270.  do until counted = 3
  271.   select
  272.    when upper(left(text.text.line, 5)) = "FROM:" then do
  273.     counted = counted + 1 ; fromline = line ; end
  274.    when upper(left(text.text.line, 8)) = "SUBJECT:" then do
  275.     counted = counted + 1 ; subjline = line ; end
  276.    when upper(left(text.text.line, 5)) = "DATE:" then do
  277.     counted = counted + 1 ; dateline = line; end
  278.    when msgoffset > 100 then do
  279.     BUFMODE ENDCOPYBACK; address(thorport); REQUESTNOTIFY '"Failed to parse digest."' '"_Ok"'; return; end
  280.  
  281.    when line > text.text.count then do
  282.     drop data. head. text.
  283.     if deldigest = 1 then do
  284.      address(bbsread); UPDATEBRMESSAGE '"'system'"' '"'mailconf'"' number SETDELETED
  285.      BUFMODE ENDCOPYBACK
  286.      if rc ~= 0 then do
  287.       address(thorport); REQUESTNOTIFY '"Couldn''t delete message #'number':\n'BBSREAD.LASTERROR'"' '"_Ok"'; end
  288.      end
  289.     return
  290.     end
  291.  
  292.    otherwise nop
  293.    end
  294.  
  295.    line = line + 1; msgoffset = msgoffset + 1
  296.   end
  297.  
  298.  newmsg.subject = "<no subject>"
  299.  newmsg.fromname = "Unknown"
  300.  newmsg.fromaddr = "<no address>"
  301.  
  302.  from = strip(substr(text.text.fromline, 6))
  303.  from = translate(from, '<>', '()')
  304.  i=pos("<", from)
  305.  if i ~= 0 then do
  306.   checkaddr = strip(substr(from, i, pos('>',from)-i), B, ' <>"')
  307.   if pos("@", checkaddr) = 0 then do
  308.    newmsg.fromname = checkaddr
  309.    newmsg.fromaddr = strip(delstr(from, i, pos('>',from)-i), B, ' >')
  310.    end
  311.   else do
  312.    newmsg.fromaddr = checkaddr
  313.    newmsg.fromname = strip(delstr(from, i, pos('>',from)-i), B, ' ">')
  314.    end
  315.   end
  316.  else do
  317.   if pos("@", from) = 0 then do
  318.    newmsg.fromname = strip(from, B, ' "')
  319.    end
  320.   else do
  321.    newmsg.fromaddr = strip(from, B, ' "')
  322.    end
  323.   end
  324.  
  325.  newmsg.subject = strip(substr(text.text.subjline, 9))
  326.  newmsg.creationdatetxt = strip(substr(text.text.dateline, 6))
  327.  
  328.  do until text.text.line ~= ''
  329.   line = line + 1
  330.   end
  331.  
  332.  firstline = line
  333.  newmsg.text.count = 0
  334.  msgline = 0
  335.  
  336.  do until compare(upper(endsubmsg), upper(text.text.line)) = 0
  337.   if line = text.text.count then break
  338.   msgline = msgline + 1
  339.   newmsg.text.count = newmsg.text.count + 1
  340.   newmsg.text.msgline = text.text.line
  341.   line = line + 1
  342.   end
  343.  
  344.  address(bbsread)
  345.  WRITEBRMESSAGE '"'system'"' '"'toconf'"' STEM newmsg
  346.  if rc ~= 0 then do
  347.   address(thorport)
  348.   REQUESTNOTIFY '"'BBSREAD.LASTERROR'"' '"_Ok"'
  349.   end
  350.  else dgsubmsgs = dgsubmsgs + 1
  351.  end
  352.  
  353.  
  354. movemsg: procedure expose thorport system mailconf conflist. data. head. text. textread
  355.          parse arg number, toconf, repaddr
  356.  
  357. CDF_NOT_ON_BBS          = '00008000'x  /* This conference is not on the bbs. */
  358.  
  359. priv = ""; urg = ""; imp = ""; kep = ""; repl = ""
  360.  
  361. if textread = 0 then do
  362.  READBRMESSAGE '"'system'"' '"'mailconf'"' number TEXTSTEM text
  363.  if rc ~= 0 then return
  364.  end
  365.  
  366. if text.TEXT.COUNT = 0 then return
  367.  
  368. if head.fromname        ~= "HEAD.FROMNAME"        then text.fromname        = head.fromname
  369. if head.fromaddr        ~= "HEAD.FROMADDR"        then text.fromaddr        = head.fromaddr
  370. if head.toname          ~= "HEAD.TONAME"          then text.toname          = head.toname
  371. if head.toaddr          ~= "HEAD.TOADDR"          then text.toaddr          = head.toaddr
  372. if head.msgid           ~= "HEAD.MSGID"           then text.msgid           = head.msgid
  373. if head.refid           ~= "HEAD.REFID"           then text.refid           = head.refid
  374. if head.creationdate    ~= "HEAD.CREATIONDATE"    then text.creationdate    = head.creationdate
  375. if head.creationdatetxt ~= "HEAD.CREATIONDATETXT" then text.creationdatetxt = head.creationdatetxt
  376. if head.subject         ~= "HEAD.SUBJECT"         then text.subject         = head.subject
  377.  
  378. do n = 1 to conflist.COUNT+1 while toconf ~= conflist.n
  379.  if n = conflist.COUNT+1 then do
  380.   address(thorport)
  381.   REQUESTNOTIFY '"Non-existant conference: 'toconf'\nDo you want to create it?"' '"_Yes|_No"'
  382.   if result = 1 then do
  383.    address(bbsread)
  384.    CONFIGCONF '"'system'"' '"'toconf'"' SET c2x(CDF_NOT_ON_BBS)
  385.    end
  386.   else return
  387.   end
  388.  end
  389.  
  390. text.replyconf = mailconf
  391. text.replyaddr = repaddr
  392.  
  393. if bittst(data.flags,2) then priv = "PRIVATE"
  394. if bittst(data.flags,11) then urg = "URGENT"
  395. if bittst(data.flags,12) then imp = "IMPORTANT"
  396.  
  397. BUFMODE COPYBACK
  398.  
  399. WRITEBRMESSAGE '"'system'"' '"'toconf'"' STEM text priv urg imp
  400. if rc ~= 0 then do
  401.  BUFMODE ENDCOPYBACK
  402.  address(thorport)
  403.  REQUESTNOTIFY '"'BBSREAD.LASTERROR'"' '"_Ok"'
  404.  return
  405.  end
  406. mnr = result
  407.  
  408. if bittst(data.flags, 7) then kep = "SETKEEP"
  409. if bittst(data.flags, 1) then repl = "SETREPLIED"
  410.  
  411. UPDATEBRMESSAGE '"'system'"' '"'toconf'"' mnr kep repl HAZELEVEL data.HAZELEVEL
  412.  
  413. UPDATEBRMESSAGE '"'system'"' '"'mailconf'"' number SETDELETED
  414. if rc ~= 0 then do
  415.  address(thorport)
  416.  REQUESTNOTIFY '"Couldn''t delete message #'number':\n'BBSREAD.LASTERROR'"' '"_Ok"'
  417.  address(bbsread)
  418.  end
  419.  
  420. BUFMODE ENDCOPYBACK
  421. drop data. head. text.
  422. return
  423.  
  424.  
  425. parseaminet: procedure expose thorport delnew system mailconf head. rparsed rfiles
  426.              parse arg number
  427.  
  428. address(thorport)
  429. SAVEMESSAGE BBS '"'system'"' CONFNAME '"'mailconf'"' MSGNUMBER number FILENAME '"T:ParseAminet.tmp"' NOHEADER NOANSI
  430. if rc ~= 0 then return
  431.  
  432. call open(rf, "T:ParseAminet.tmp")
  433.  
  434. if left(readln(rf), 1) ~= '|' then do
  435.  address command
  436.  call close(rf)
  437.  'Delete T:ParseAminet.tmp QUIET'
  438.  return
  439.  end
  440.  
  441. rparsed = rparsed + 1
  442.  
  443. address(bbsread)
  444. BUFMODE COPYBACK
  445.  
  446. do until eof(rf)
  447.  aline = readln(rf)
  448.  do while(left(aline, 1) = '|'); aline = readln(rf); end
  449.  if aline ~= "" then do
  450.   farea = word(aline, 2)
  451.   CONFIGFAREA '"'system'"' '"'farea'"'
  452.  
  453.   fname = word(aline, 1)
  454.   fdesc = right(aline, length(aline) - 35)
  455.   fsize = right(left(aline, 34), 5)
  456.   if(right(fsize, 1) = 'M') then mega = 1
  457.   else mega = 0
  458.  
  459.   fsize = compress(fsize, 'KM .')
  460.  
  461.   if(~datatype(fsize, 'W')) then fsize = 0
  462.   fsize = fsize * 1024
  463.   if(mega = 1) then fsize = trunc((fsize * 1024) / 10)
  464.  
  465.   if(fdesc ~= '') then do
  466.    drop brfile.
  467.    brfile.NAME = fname
  468.    brfile.SIZE = fsize
  469.    brfile.DATE = head.CREATIONDATE
  470.    brfile.DESCRIPTION.COUNT = 1
  471.    brfile.DESCRIPTION.1 = strip(fdesc)
  472.    WRITEBRFILE '"'system'"' '"'farea'"' STEM brfile
  473.    rfiles = rfiles + 1
  474.    end
  475.   end
  476.  end
  477. call close(rf)
  478.  
  479. address(bbsread)
  480. GETBBSDATA '"'system'"' bbsdata
  481.  
  482. if delnew = 0 then if exists(bbsdata.BBSPATH'Newfiles.txt') then do
  483.  address(command)
  484.  'Delete "'bbsdata.BBSPATH'Newfiles.txt" QUIET'
  485.  delnew = 1
  486.  end
  487.  
  488. address(thorport)
  489. SAVEMESSAGE BBS '"'system'"' CONFNAME '"'mailconf'"' MSGNUMBER number FILENAME '"'bbsdata.BBSPATH'Newfiles.txt"' NOHEADER NOANSI
  490.  
  491. address(bbsread)
  492. UPDATEBRMESSAGE '"'system'"' '"'mailconf'"' number SETDELETED
  493. if rc ~= 0 then do
  494.  address(thorport)
  495.  REQUESTNOTIFY '"Couldn''t delete message #'number':\n'BBSREAD.LASTERROR'"' '"_Ok"'
  496.  address(bbsread)
  497.  end
  498.  
  499. BUFMODE ENDCOPYBACK
  500.  
  501. address command
  502. 'Delete T:ParseAminet.tmp QUIET'
  503.  
  504. drop head. data. text.
  505.  
  506. return
  507.  
  508.  
  509. readcfg: procedure expose cfgfile system mailconf aminet amirep checkcc mlist. digest. mlcount dgcount stats
  510.  
  511. /* Open and read configuration file */
  512. call open(cf, cfgfile, 'R')
  513. do until eof(cf)
  514.  subentry = ""
  515.  entry = readln(cf)
  516.  select
  517.   when upper(entry) = "SYSTEM" then do until upper(subentry) = "END"
  518.    subentry = readln(cf)
  519.    select
  520.     when upper(subword(subentry, 1, 1)) = 'BBS:' then system = subword(subentry, 2)
  521.     when upper(subword(subentry, 1, 1)) = 'CONF:' then mailconf = subword(subentry, 2)
  522.     when upper(subword(subentry, 1, 1)) = 'AMINET:' then aminet = subword(subentry, 2)
  523.     when upper(subword(subentry, 1, 1)) = 'AMIREP:' then amirep = subword(subentry, 2)
  524.     when upper(subword(subentry, 1, 1)) = 'CHECKCC:' then if upper(subword(subentry, 2, 1)) = 'YES' then checkcc = 1
  525.     when upper(subword(subentry, 1, 1)) = 'STATISTICS:' then if upper(subword(subentry, 2, 1)) = 'YES' then stats = 1
  526.     otherwise nop
  527.     end
  528.    end
  529.  
  530.   when upper(entry) = "MAILLIST" then do
  531.    mlcount = mlcount + 1
  532.    addrs = 0; names = 0
  533.    do until upper(subentry) = "END"
  534.     subentry = readln(cf)
  535.     select
  536.      when upper(subword(subentry, 1, 1)) = 'LISTNAME:' then mlist.mlcount.name = subword(subentry, 2)
  537.      when upper(subword(subentry, 1, 1)) = 'TOADDR:' then do
  538.       addrs = addrs + 1
  539.       mlist.mlcount.toaddr.addrs = subword(subentry, 2)
  540.       end
  541.      when upper(subword(subentry, 1, 1)) = 'TONAME:' then do
  542.       names = names + 1
  543.       mlist.mlcount.toname.names = subword(subentry, 2)
  544.       end
  545.      when upper(subword(subentry, 1, 1)) = 'REPLYADDR:' then mlist.mlcount.replyaddr = subword(subentry, 2)
  546.      otherwise nop
  547.      end
  548.     mlist.mlcount.addrcount = addrs
  549.     mlist.mlcount.namecount = names
  550.     end
  551.    end
  552.  
  553.   when upper(entry) = "DIGEST" then do
  554.    dgcount = dgcount + 1
  555.    addrs = 0; names = 0
  556.    digest.dgcount.deldigest = 0
  557.    do until upper(subentry) = "END"
  558.     subentry = readln(cf)
  559.     select
  560.      when upper(subword(subentry, 1, 1)) = 'DIGESTNAME:' then digest.dgcount.name = subword(subentry, 2)
  561.      when upper(subword(subentry, 1, 1)) = 'TOADDR:' then do
  562.       addrs = addrs + 1
  563.       digest.dgcount.toaddr.addrs = subword(subentry, 2)
  564.       end
  565.      when upper(subword(subentry, 1, 1)) = 'TONAME:' then do
  566.       names = names + 1
  567.       digest.dgcount.toname.names = subword(subentry, 2)
  568.       end
  569.      when upper(subword(subentry, 1, 1)) = 'REPLYADDR:' then digest.dgcount.replyaddr = subword(subentry, 2)
  570.      when upper(subword(subentry, 1, 1)) = 'ENDSUBMSG:' then digest.dgcount.endsubmsg = subword(subentry, 2)
  571.      when upper(subword(subentry, 1, 1)) = 'ENDDIGEST:' then digest.dgcount.enddigest = subword(subentry, 2)
  572.      when upper(subword(subentry, 1, 1)) = 'DELDIGEST:' then if upper(subword(subentry, 2, 1)) = 'YES' then digest.dgcount.deldigest = 1
  573.      otherwise nop
  574.      end
  575.     digest.dgcount.addrcount = addrs
  576.     digest.dgcount.namecount = names
  577.     end
  578.    end
  579.   otherwise nop
  580.   end
  581.  end
  582. call close(cf)
  583. return
  584.  
  585. cleanup: procedure expose progwin thorport
  586.  
  587. address(bbsread)
  588. BUFMODE ENDCOPYBACK
  589.  
  590. if progwin ~= 0 then do
  591.  address(thorport)
  592.  CLOSEPROGRESS REQ progwin
  593.  end
  594.  
  595. if exists("T:SortMail.tmp") then do
  596.  address(command)
  597.  "Delete T:SortMail.tmp QUIET"
  598.  end
  599.  
  600. exit(0)
  601.